#include "8bit.h"
#include "cp1250cvt.h"

using namespace std;


static const wchar_t cp2ucs[] = {
	0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
	0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
	0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
	0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
	0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
	0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
	0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
	0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
	0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
	0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
	0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
	0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
	0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
	0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
	0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
};

static const struct cw ucs2cp[] = {
	{0xA0, 0x00A0}, {0xA4, 0x00A4}, {0xA6, 0x00A6}, {0xA7, 0x00A7},
	{0xA8, 0x00A8}, {0xA9, 0x00A9}, {0xAB, 0x00AB}, {0xAC, 0x00AC},
	{0xAD, 0x00AD}, {0xAE, 0x00AE}, {0xB0, 0x00B0}, {0xB1, 0x00B1},
	{0xB4, 0x00B4}, {0xB5, 0x00B5}, {0xB6, 0x00B6}, {0xB7, 0x00B7},
	{0xB8, 0x00B8}, {0xBB, 0x00BB}, {0xC1, 0x00C1}, {0xC2, 0x00C2},
	{0xC4, 0x00C4}, {0xC7, 0x00C7}, {0xC9, 0x00C9}, {0xCB, 0x00CB},
	{0xCD, 0x00CD}, {0xCE, 0x00CE}, {0xD3, 0x00D3}, {0xD4, 0x00D4},
	{0xD6, 0x00D6}, {0xD7, 0x00D7}, {0xDA, 0x00DA}, {0xDC, 0x00DC},
	{0xDD, 0x00DD}, {0xDF, 0x00DF}, {0xE1, 0x00E1}, {0xE2, 0x00E2},
	{0xE4, 0x00E4}, {0xE7, 0x00E7}, {0xE9, 0x00E9}, {0xEB, 0x00EB},
	{0xED, 0x00ED}, {0xEE, 0x00EE}, {0xF3, 0x00F3}, {0xF4, 0x00F4},
	{0xF6, 0x00F6}, {0xF7, 0x00F7}, {0xFA, 0x00FA}, {0xFC, 0x00FC},
	{0xFD, 0x00FD}, {0xC3, 0x0102}, {0xE3, 0x0103}, {0xA5, 0x0104},
	{0xB9, 0x0105}, {0xC6, 0x0106}, {0xE6, 0x0107}, {0xC8, 0x010C},
	{0xE8, 0x010D}, {0xCF, 0x010E}, {0xEF, 0x010F}, {0xD0, 0x0110},
	{0xF0, 0x0111}, {0xCA, 0x0118}, {0xEA, 0x0119}, {0xCC, 0x011A},
	{0xEC, 0x011B}, {0xC5, 0x0139}, {0xE5, 0x013A}, {0xBC, 0x013D},
	{0xBE, 0x013E}, {0xA3, 0x0141}, {0xB3, 0x0142}, {0xD1, 0x0143},
	{0xF1, 0x0144}, {0xD2, 0x0147}, {0xF2, 0x0148}, {0xD5, 0x0150},
	{0xF5, 0x0151}, {0xC0, 0x0154}, {0xE0, 0x0155}, {0xD8, 0x0158},
	{0xF8, 0x0159}, {0x8C, 0x015A}, {0x9C, 0x015B}, {0xAA, 0x015E},
	{0xBA, 0x015F}, {0x8A, 0x0160}, {0x9A, 0x0161}, {0xDE, 0x0162},
	{0xFE, 0x0163}, {0x8D, 0x0164}, {0x9D, 0x0165}, {0xD9, 0x016E},
	{0xF9, 0x016F}, {0xDB, 0x0170}, {0xFB, 0x0171}, {0x8F, 0x0179},
	{0x9F, 0x017A}, {0xAF, 0x017B}, {0xBF, 0x017C}, {0x8E, 0x017D},
	{0x9E, 0x017E}, {0xA1, 0x02C7}, {0xA2, 0x02D8}, {0xFF, 0x02D9},
	{0xB2, 0x02DB}, {0xBD, 0x02DD}, {0x96, 0x2013}, {0x97, 0x2014},
	{0x91, 0x2018}, {0x92, 0x2019}, {0x82, 0x201A}, {0x93, 0x201C},
	{0x94, 0x201D}, {0x84, 0x201E}, {0x86, 0x2020}, {0x87, 0x2021},
	{0x95, 0x2022}, {0x85, 0x2026}, {0x89, 0x2030}, {0x8B, 0x2039},
	{0x9B, 0x203A}, {0x80, 0x20AC}, {0x99, 0x2122}
};


codecvt_base::result cp1250cvt::do_in(mbstate_t&, const char* from,
  const char* from_end, const char*& from_next, wchar_t* to,
  wchar_t* to_limit, wchar_t*& to_next) const
{
	return ::do_in(from, from_end, from_next, to, to_limit, to_next, 0x80,
	  cp2ucs) ? codecvt_base::error : codecvt_base::ok;
}

codecvt_base::result cp1250cvt::do_out(mbstate_t&, const wchar_t* from,
  const wchar_t* from_end, const wchar_t*& from_next, char* to,
  char* to_limit, char*& to_next) const
{
	return ::do_out(from, from_end, from_next, to, to_limit, to_next, 0x80,
	  ucs2cp, sizeof(ucs2cp)) ? codecvt_base::error : codecvt_base::ok;
}

codecvt_base::result cp1250cvt::do_unshift(mbstate_t&, char* to, char*,
  char*& to_next) const
{
	to_next = to;

	return codecvt_base::noconv;
}
